rule:
meta:
name: enumerate PE sections
namespace: load-code/pe
authors:
- "@Ana06"
- "@mr-tz"
scopes:
static: function
dynamic: unsupported # requires offset, operand[1].offset, characteristic, mnemonic, basicblock features
mbc:
- Discovery::Code Discovery::Enumerate PE Sections [B0046.001]
references:
- https://0x00sec.org/t/reflective-dll-injection/3080
- https://www.ired.team/offensive-security/code-injection-process-injection/reflective-dll-injection
examples:
- E4C33AC3638EEF68311F8AC0D72483C7:0x401510
features:
- and:
- os: windows
# there should be some complexity to functions like this
- count(basic blocks): 3 or more
- optional:
- offset: 0x3C = IMAGE_DOS_HEADER.e_lfanew
- instruction:
- or:
- mnemonic: mov
- mnemonic: movzx
- operand[1].offset: 0x6 = IMAGE_NT_HEADERS.FileHeader.NumberOfSections
- basic block:
- or:
- and:
- description: IMAGE_FIRST_SECTION(nt_header)
- instruction:
- or:
- mnemonic: add
- mnemonic: mov
- mnemonic: movzx
- operand[1].offset: 0x14 = IMAGE_NT_HEADERS.FileHeader.SizeOfOptionalHeader
- operand[1].offset: 0x18 = FileHeader.SizeOfOptionalHeader
- and:
- description: (DWORD)dll_raw + dos_header->e_lfanew + sizeof(IMAGE_NT_HEADERS) + sizeof(IMAGE_SECTION_HEADER) * i
- number: 0x28 = sizeof(IMAGE_SECTION_HEADER)
- or:
- and:
- arch: i386
- operand[1].offset: 0xF8 = sizeof(IMAGE_NT_HEADERS32)
- and:
- arch: amd64
- operand[1].offset: 0x108 = sizeof(IMAGE_NT_HEADERS64)
- 2 or more:
- operand[1].offset: 0xC = IMAGE_SECTION_HEADER.VirtualAddress
- operand[1].offset: 0x14 = IMAGE_SECTION_HEADER.PointerToRawData
- operand[1].offset: 0x10 = IMAGE_SECTION_HEADER.SizeOfRawData
# there's also offset 0x8 = IMAGE_SECTION_HEADER.Misc.PhysicalAddress, but it's likely too common
- not:
# non-zeroing XOR was observed in FPs
- characteristic: nzxor
last edited: 2023-11-24 10:35:05